package com.macro.mall.portal.controller.pay;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.macro.mall.boot.wechatpay.config.WxPayConfiguration;
import com.macro.mall.common.api.exception.BusinessException;
import com.macro.mall.common.api.util.StringUtils;
import com.macro.mall.oms.entity.OrderEntity;
import com.macro.mall.oms.service.order.OrderService;
import com.macro.mall.oms.service.order.bo.UpdateOrderInput;
import com.macro.mall.portal.service.OmsPortalOrderService;
import com.macro.mall.ums.enums.UserSourceTypeEnum;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;

/**
 * 微信支付回调控制器
 *
 * @author xuyanjun
 * @date 2019-10-26
 */
@Api(tags = "WeChatPayCallbackController", description = "微信支付回调")
@RestController
@Slf4j(topic = "WeChatPayCallbackController")
public class WeChatPayCallbackController {

    @Autowired
    private OmsPortalOrderService portalOrderService;

    @Autowired
    private OrderService orderService;

    @PostMapping("/pay/callback/weChat/v1")
    public String notifyV1(@RequestBody String xmlData) {
        try {
            log.debug("微信支付异步通知请求参数v1：{}", xmlData);
            WxPayOrderNotifyResult wxPayOrderNotifyResult = WxPayOrderNotifyResult.fromXML(xmlData);
            log.info("微信支付异步通知请求解析后的对象v1：{}", wxPayOrderNotifyResult);

            if (!isWxResultSuccess(wxPayOrderNotifyResult)) {
                throw new BusinessException(wxPayOrderNotifyResult.getReturnMsg());
            }

            // attach ="orderType-orderId-appId"
            String attach = wxPayOrderNotifyResult.getAttach();

            WxPayService wxPayService = WxPayConfiguration.getWxPayServiceByBusinessAppId(UserSourceTypeEnum.WX_MP.getValue());

            // 校验签名
            wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(xmlData);

            portalOrderService.paySuccess(Long.valueOf(attach));

            return WxPayNotifyResponse.success("成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("微信支付回调通知v1失败:{}", e.getMessage());
            return WxPayNotifyResponse.fail("失败");
        }
    }

    /**
     * 微信响应结果是否成功
     *
     * @param baseWxPayResult 微信响应结果
     * @return 是否成功
     */
    private boolean isWxResultSuccess(BaseWxPayResult baseWxPayResult) {
        return WxPayConstants.ResultCode.SUCCESS.equals(baseWxPayResult.getReturnCode()) &&
                WxPayConstants.ResultCode.SUCCESS.equals(baseWxPayResult.getResultCode());
    }


    @PostMapping("/refund/callback/weChat/v1")
    public String refundV1(@RequestBody String xmlData) {
        try {
            log.debug("微信退款异步通知请求参数v1：{}", xmlData);

            WxPayService wxPayService = WxPayConfiguration.getWxPayServiceByBusinessAppId(UserSourceTypeEnum.WX_MP.getValue());

            final WxPayRefundNotifyResult wxPayRefundNotifyResult = WxPayRefundNotifyResult.fromXML(xmlData, wxPayService.getConfig().getMchKey());
            log.info("微信退款异步通知请求参数v1：{}", wxPayRefundNotifyResult);

            if (!isWxResultSuccess(wxPayRefundNotifyResult)) {
                throw new BusinessException(wxPayRefundNotifyResult.getReturnMsg());
            }

            // attach ="ret-orderNo-orderId"
            String attach = wxPayRefundNotifyResult.getReqInfo().getOutTradeNo();

            final Long orderId =Long.valueOf( StringUtils.split(attach, "-")[2]);
            final OrderEntity orderEntity = orderService.getById(orderId);
            if(orderEntity.getRefundTime()!=null)
            {
                return WxPayNotifyResponse.success("成功");
            }

            UpdateOrderInput updateOrderInput=new UpdateOrderInput();
            updateOrderInput.setId(orderId)
                    .setRefundTime(LocalDateTime.now());

            orderService.update(updateOrderInput);

            return WxPayNotifyResponse.success("成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("微信退款回调通知v1失败:{}", e.getMessage());
            return WxPayNotifyResponse.fail("失败");
        }
    }
}
